package com.example.practicespring.controller.userChange;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.practicespring.domain.*;
import com.example.practicespring.service.*;
import com.example.practicespring.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.expression.Lists;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.example.practicespring.ConstantConfig.ConstantConfig.imgPath;
import static com.example.practicespring.utils.PwdUtils.checkPassword;
import static com.example.practicespring.utils.PwdUtils.getSHA256Hash;

@Slf4j
@RestController
@RequestMapping(value = "/userChange")
public class userChange {

    @Resource
    private UserService userService;

    @Resource
    private SysUserRoleService sysUserRoleService;

    @Resource
    private SysRoleMenuService sysRoleMenuService;

    @Resource
    private SysMenuService sysMenuService;

    @Resource
    private SysRoleService sysRoleService;

    @SaCheckRole(value = {"admin", "user", "tour"}, mode = SaMode.OR)
    @RequestMapping(value = "/changePasswd", method = RequestMethod.POST)
    public SaResult changePasswd(@RequestBody User user) { // 修改密码
        if (user == null) {
            return SaResult.error("用户不存在");
        }
        User oldUser = userService.getById(user.getId());

        if (!oldUser.getPasswd().equals(getSHA256Hash(user.getPasswd()))) { // 判断旧密码是否正确
            return SaResult.error("旧密码错误");
        }

        if (!checkPassword(user.getNewPassword())) {
            return SaResult.error("密码不符合要求: 包含大小写字母、数字和特殊字符，长度至少为8");
        }
        oldUser.setPasswd(getSHA256Hash(user.getNewPassword()));
        if (userService.updateById(oldUser)) {
            return SaResult.ok("密码修改成功");
        } else {
            return SaResult.error("密码修改失败");
        }
    }

    @SaCheckRole(value = {"admin", "user", "tour"}, mode = SaMode.OR)
    @RequestMapping(value = "/logOut", method = RequestMethod.POST)
    public SaResult logOut(@RequestBody User user) { // 退出登录
        if (user == null) {
            return SaResult.error("用户不存在");
        }
        User outUser = userService.getById(user.getId());
        StpUtil.logoutByTokenValue(outUser.getToken());
        outUser.setToken("");
        if (userService.updateById(outUser)) {
            return SaResult.ok("退出登录成功");
        } else {
            return SaResult.error("退出登录失败");
        }
    }

    @SaCheckRole(value = "admin")
    @RequestMapping(value = "/changeState", method = RequestMethod.POST)
    public SaResult changeState(@RequestBody User user) { // 修改用户状态
        if (user == null) {
            return SaResult.error("用户不存在");
        }

        if (user.getIsActive() == 1) {
            QueryWrapper<SysRole> roleQueryWrapper = new QueryWrapper<>();
            roleQueryWrapper.eq("name", "admin");
            SysRole adminRole = sysRoleService.getOne(roleQueryWrapper);

            // 管理员至少保证一个能正常登录
            QueryWrapper<SysUserRole> roleCheck = new QueryWrapper<>();
            roleCheck.eq("userId", user.getId());
            if (Objects.equals(sysUserRoleService.getOne(roleCheck).getRoleid(), adminRole.getId())) {
                QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
                sysUserRoleQueryWrapper.eq("roleId", adminRole.getId());
                if (sysUserRoleService.count(sysUserRoleQueryWrapper) < 2) {
                    return SaResult.error("至少保留一个管理员正常登录");
                }
            }
        }

        User changeUser = userService.getById(user.getId());
        if (changeUser.getIsActive() == 0) {
            changeUser.setIsActive(1);
        } else {
            changeUser.setIsActive(0);
        }
        if (userService.updateById(changeUser)) {
            return SaResult.ok("状态修改成功");
        } else {
            return SaResult.error("状态修改失败");
        }
    }

    @SaCheckRole(value = "admin")
    @RequestMapping(value = "/delUser", method = RequestMethod.POST)
    public SaResult delUser(@RequestBody User user) { // 删除用户
        if (user == null) {
            return SaResult.error("用户不存在");
        }
        User delUser = userService.getById(user.getId());
        if (userService.removeById(delUser)) {
            return SaResult.ok("用户删除成功");
        } else {
            return SaResult.error("用户删除失败");
        }
    }

    @SaCheckRole(value = {"admin", "user", "tour"}, mode = SaMode.OR)
    @RequestMapping(value = "/changeImg", method = RequestMethod.POST)
    public SaResult changeImg(@RequestParam("file") MultipartFile headImg, HttpServletRequest request) {
        // 检查文件是否为空
        if (headImg.isEmpty()) {
            return null;
        }
        // 获取文件名
        String fileName = headImg.getOriginalFilename();
        log.info("文件名：{}", fileName);

        String newName = StringUtils.getUUID() + (fileName.contains(".") ? fileName.substring(fileName.lastIndexOf('.')) : "");
        // 你可以在这里处理文件，例如保存到服务器
        try {
            headImg.transferTo(new File(imgPath + newName));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 返回成功结果
        return SaResult.data(Collections.singletonList(new JSONObject().fluentPut("uid", "-1").fluentPut("name", newName).fluentPut("status", "down").fluentPut("url", newName)));
    }

    @SaCheckRole(value = {"admin", "user", "tour"}, mode = SaMode.OR)
    @RequestMapping(value = "/subChangeImg", method = RequestMethod.POST)
    public SaResult subChangeImg(@RequestBody User user) {
        user.setUserimg(user.getUserImgList().get(0).get("name"));
        userService.updateById(user);
        return SaResult.ok("头像更新成功！");
    }

    @SaCheckRole(value = {"admin", "user", "tour"}, mode = SaMode.OR)
    @RequestMapping(value = "/getUser", method = RequestMethod.GET)
    public SaResult getUser(@RequestParam("id") String id) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("id", id);
        User user = userService.getOne(wrapper);
        return SaResult.ok().setData(user);
    }

    @SaCheckRole(value = {"admin", "user", "tour"}, mode = SaMode.OR)
    @RequestMapping(value = "/getMenu", method = RequestMethod.GET)
    public SaResult getMenu(@RequestParam("id") String id) {
        // 查询roleid
        QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
        sysUserRoleQueryWrapper.eq("userId", id);
        SysUserRole sysUserRole = sysUserRoleService.getOne(sysUserRoleQueryWrapper);
        // 查询角色对应的菜单id
        QueryWrapper<SysRoleMenu> sysRoleMenuQueryWrapper = new QueryWrapper<>();
        sysRoleMenuQueryWrapper.eq("roleId", sysUserRole.getRoleid());
        List<Integer> menuList = sysRoleMenuService.list(sysRoleMenuQueryWrapper).stream().map(SysRoleMenu::getMenuid).collect(Collectors.toList());

        // 查询菜单信息
        QueryWrapper<SysMenu> sysMenuQueryWrapper = new QueryWrapper<>();
        sysMenuQueryWrapper.in("id", menuList);
        sysMenuQueryWrapper.orderByAsc("ord");
        List<SysMenu> sysMenuList = sysMenuService.list(sysMenuQueryWrapper);

        // 菜单查询结果
        List<JSONObject> menuResult = new ArrayList<>();
        for (SysMenu menu : sysMenuList) {
            JSONObject menuMap = new JSONObject();
            JSONObject tmp = new JSONObject();
            if (menu.getPid() == 0) {
                tmp.put("title", menu.getTitle());
                tmp.put("url", menu.getUrl());
                tmp.put("icon", menu.getIcon());
                tmp.put("id", menu.getId());
                menuMap.put("parent", tmp);

                // 寻找子菜单
                List<JSONObject> tmpChild = new ArrayList<>();
                for (SysMenu childMenu : sysMenuList) {
                    JSONObject childMap = new JSONObject();
                    if (Objects.equals(childMenu.getPid(), menu.getId())) {
                        childMap.put("title", childMenu.getTitle());
                        childMap.put("url", childMenu.getUrl());
                        childMap.put("icon", childMenu.getIcon());
                        childMap.put("id", childMenu.getId());
                        tmpChild.add(childMap);
                    }
                }
                if (!tmpChild.isEmpty()) {
                    menuMap.put("children", tmpChild);
                }
            }
            if (!menuMap.isEmpty()) {
                menuResult.add(menuMap);
            }
        }
        return SaResult.data(menuResult);
    }

    @SaCheckRole(value = "admin")
    @RequestMapping(value = "/setRole", method = RequestMethod.POST)
    public SaResult setRole(@RequestBody User user) {
        if (user == null) {
            return SaResult.error("信息为空");
        }

        QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
        List<SysRole> sysRoles = sysRoleService.list(sysRoleQueryWrapper);
        JSONObject roleMap = new JSONObject();
        for (SysRole sysRole : sysRoles) {
            roleMap.put(sysRole.getName(), sysRole.getId());
        }

        QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
        sysUserRoleQueryWrapper.eq("userId", user.getId());
        SysUserRole sysUserRole = sysUserRoleService.getOne(sysUserRoleQueryWrapper);

        // 至少拥有一个管理员
        if (sysUserRole.getRoleid().toString().equals(roleMap.getString("admin"))){
            if (!Objects.equals(user.getRoleName(), "admin")) {
            QueryWrapper<SysUserRole> roleCheck = new QueryWrapper<>();
            roleCheck.eq("roleId", roleMap.getInteger("admin"));

            if (sysUserRoleService.count(roleCheck) < 2) {
                return SaResult.error("至少保留一个管理员");
            }
        }
        }

        sysUserRole.setRoleid(roleMap.getInteger(user.getRoleName()));
        sysUserRoleService.updateById(sysUserRole);

        return SaResult.ok("角色更新成功");
    }
}

